﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web;
using System.Web.Routing;
using WarOfDev.EF;
using WarOfDev.Core.StateManagentHelpers;
using WarOfDev.Core.ExceptionHandling.Exceptions;
using WarOfDev.Core.ExceptionHandling.ExceptionDetails;

namespace WarOfDev.Core.ActionFilters
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="CustomAuthorizeAttribute"/> class.
        /// </summary>
        /// <param name="action">The action.</param>
        /// <param name="controller">The controller.</param>
        public CustomAuthorizeAttribute(string action, string controller)
        {
            this.Action = action;
            this.Controller = controller;
        }

        public CustomAuthorizeAttribute(string permission)
        {
            this.Permission = permission;
        }

        /// <summary>
        /// Gets the action.
        /// </summary>
        public string Action { get; private set; }

        /// <summary>
        /// Gets the controller.
        /// </summary>
        public string Controller { get; private set; }

        public string Permission { get; private set; }

        public User UserToken { get; private set; }

        public bool IsAuthorized { get; private set; }

        /// <summary>
        /// When overridden, provides an entry point for custom authorization checks.
        /// </summary>
        /// <param name="httpContext">The HTTP context, which encapsulates all HTTP-specific information about an individual HTTP request.</param>
        /// <returns>
        /// true if the user is authorized; otherwise, false.
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="httpContext"/> parameter is null.</exception>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }

            this.IsAuthorized = false;
            this.UserToken = SecurityTokenHelper<User>.GetSecurityToken(httpContext);

            if (this.UserToken != null && this.UserToken.Permissions != null)
            {
                this.IsAuthorized = this.UserToken.Permissions.Where(p => p.PermissionName == this.Permission).Count() > 0;
            }

            return this.IsAuthorized;
        }

        /// <summary>
        /// Handles the unauthorized request.
        /// </summary>
        /// <param name="context">The MVC Authorization Context.</param>
        protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext context)
        {
            var httpcontext = context.HttpContext;

            if (this.UserToken != null && !this.IsAuthorized)
            {
                throw new WofException<FrontendDetail>("no permission", null, new FrontendDetail(10101, "no permission"));
            }
            else
            {
                throw new WofException<FrontendDetail>("Session timeout", null, new FrontendDetail(10201, "Session timeout"));
            }
        }

    }
}
